package org.SimpleSpringBoot.container;

import org.SimpleSpringBoot.annotation.*;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/*
组件扫描器，负责扫描指定包下的组件类
 */
public class ComponentScanner {

    /*
    扫描指定包下的所有组件
     */
    public List<Class<?>> scanComponents(String basePackage){
        List<Class<?>> componentss=new ArrayList<>();
        try {
            //将包名转化为路径
            String packagePath=basePackage.replace('.','/');

            //获取包的URL
            ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
            URL packageURL =classLoader.getResource(packagePath);
            if (packageURL!=null){
                //扫描包下的所有类文件
                File packageDir =new File(packageURL.getFile());
                scanDirectory(packageDir,basePackage,componentss);
            }
        }catch (Exception e){

        System.err.println("扫描组件时发生错误:"+e.getMessage());
        }
    return componentss;
    }

    private void scanDirectory(File directory, String packageName, List<Class<?>> componentss) {
        if (!directory.exists()||!directory.isDirectory()){
            return;
        }
        File[] files=directory.listFiles();
        if (files==null){
            return;
        }
        for (File file : files) {
            if (file.isDirectory()){
                //递归扫描子目录
                scanDirectory(file,packageName+"."+file
                        .getName(),componentss);
            } else if (file.getName().endsWith(".class")) {
                //处理类文件
                String classsName=packageName+"."+file.getName().substring(0, file.getName().length()-6);
                try {
                    Class<?> clazz=Class.forName(classsName);
                    if (isComponent(clazz)){
                        componentss.add(clazz);
                        System.out.println("发现组件:"+clazz.getSimpleName());
                    }
                }catch (ClassNotFoundException e){
                    System.out.println("加载失败:"+classsName);
                }

            }
        }
    }

    /*
    判断类是否为组件
     */
    private boolean isComponent(Class<?> clazz) {
        // 修复点1：排除注解类
        if (clazz.isAnnotation()) {
            System.out.println("跳过注解类: " + clazz.getSimpleName());
            return false;
        }

        // 修复点2：排除接口
        if (clazz.isInterface()) {
            System.out.println("跳过接口类: " + clazz.getSimpleName());
            return false;
        }

        // 修复点3：排除抽象类
        if (java.lang.reflect.Modifier.isAbstract(clazz.getModifiers())) {
            System.out.println("跳过抽象类: " + clazz.getSimpleName());
            return false;
        }

        // 修复点4：排除枚举类
        if (clazz.isEnum()) {
            System.out.println("跳过枚举类: " + clazz.getSimpleName());
            return false;
        }

        // 修复点5：排除匿名类和局部类
        if (clazz.isAnonymousClass() || clazz.isLocalClass()) {
            System.out.println("跳过匿名类或局部类: " + clazz.getSimpleName());
            return false;
        }

        // 修复点6：确保类有无参构造器或者至少有一个可访问的构造器
        if (!hasValidConstructor(clazz)) {
            System.out.println("跳过没有有效构造器的类: " + clazz.getSimpleName());
            return false;
        }

        // 检查是否有组件注解
        boolean hasComponentAnnotation = clazz.isAnnotationPresent(Component.class) ||
                clazz.isAnnotationPresent(Service.class) ||
                clazz.isAnnotationPresent(Repository.class) ||
                clazz.isAnnotationPresent(Controller.class) ||
                clazz.isAnnotationPresent(Configuration.class);

        return hasComponentAnnotation;
    }

    /**
     * 检查类是否有有效的构造器
     */
    private boolean hasValidConstructor(Class<?> clazz) {
        try {
            // 检查是否有无参构造器
            clazz.getDeclaredConstructor();
            return true;
        } catch (NoSuchMethodException e) {
            // 如果没有无参构造器，检查是否有其他构造器
            java.lang.reflect.Constructor<?>[] constructors = clazz.getDeclaredConstructors();
            return constructors.length > 0;
        } catch (Exception e) {
            return false;
        }
    }


    /*
    获取Bean的名字
     */
    public String getBeanName(Class<?> clazz){
        String beanName=null;

        if (clazz.isAnnotationPresent(Component.class)){
            beanName=clazz.getAnnotation(Component.class).value();
        } else if (clazz.isAnnotationPresent(Service.class)) {
            beanName=clazz.getAnnotation(Service.class).value();
        } else if (clazz.isAnnotationPresent(Repository.class)) {
            beanName=clazz.getAnnotation(Repository.class).value();
        } else if (clazz.isAnnotationPresent(Controller.class)) {
            beanName=clazz.getAnnotation(Controller.class).value();
        } else if (clazz.isAnnotationPresent(Configuration.class)) {
            beanName=clazz.getAnnotation(Configuration.class).value();
        }
    //如果没有指定名称，使用类名的小写形式
        if (beanName==null||beanName.isEmpty()){
            beanName= clazz.getSimpleName().substring(0,1).toLowerCase()+clazz.getSimpleName()
                    .substring(1);
        }
        return beanName;

    }

}
